package com.example.cloud.interceptor;

import com.example.cloud.exception.AuthException;
import com.example.cloud.util.Result;
import com.example.cloud.util.JwtUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import java.io.IOException;

/**
 * 认证拦截器
 * 处理token验证和用户ID提取
 */
@Component
@RequiredArgsConstructor
public class AuthInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(AuthInterceptor.class);
    private static final String AUTH_HEADER = "Authorization";
    private static final String USER_ID_ATTRIBUTE = "userId";
    private static final String BEARER_PREFIX = "Bearer ";

    private final ObjectMapper objectMapper;
    private final JwtUtil jwtUtil;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 获取请求路径
        String path = request.getRequestURI();
        
        // 不需要认证的路径直接放行
        if (isExcludedPath(path)) {
            return true;
        }
        
        // 获取token
        String authHeader = request.getHeader(AUTH_HEADER);
        if (authHeader == null || !authHeader.startsWith(BEARER_PREFIX)) {
            throw new AuthException("未登录或token已过期");
        }
        
        // 提取token
        String token = authHeader.substring(BEARER_PREFIX.length());
        
        try {
            // 验证token
            if (!jwtUtil.validateToken(token)) {
                throw new AuthException("token已过期");
            }
            
            // 从token中获取用户ID
            Long userId = jwtUtil.getUserIdFromToken(token);
            if (userId == null) {
                throw new AuthException("无效的token：未找到用户ID");
            }
            
            // 将用户ID存入请求属性
            request.setAttribute(USER_ID_ATTRIBUTE, userId);
            
            return true;
        } catch (AuthException e) {
            throw e;
        } catch (Exception e) {
            logger.error("token验证失败", e);
            throw new AuthException("token验证失败：" + e.getMessage(), e);
        }
    }
    
    /**
     * 判断是否为排除认证的路径
     * @param path 请求路径
     * @return 是否排除
     */
    private boolean isExcludedPath(String path) {
        // 登录接口不需要认证
        if (path.startsWith("/api/auth/wx-login")) {
            return true;
        }
        
        // 静态资源不需要认证
        if (path.startsWith("/uploads/") || path.startsWith("/static/")) {
            return true;
        }
        
        // Swagger相关路径不需要认证
        if (path.startsWith("/swagger-ui") || path.startsWith("/v3/api-docs")) {
            return true;
        }
        
        // 健康检查不需要认证
        if (path.equals("/health") || path.equals("/")) {
            return true;
        }
        
        return false;
    }
    
    /**
     * 从请求中获取当前用户ID
     * @param request HTTP请求
     * @return 用户ID
     */
    public static Long getCurrentUserId(HttpServletRequest request) {
        Object userId = request.getAttribute(USER_ID_ATTRIBUTE);
        return userId != null ? (Long) userId : null;
    }
} 